/**
 * 基础图层类
 * 所有图层类的父类，封装通用逻辑和数据管理能力
 */

import { Map as OlMap } from 'ol';
import { Layer as OlLayer } from 'ol/layer';
import { Feature } from 'ol';
import { BaseLayerOptions, DataAdapterOptions, DataSourceType, LoadProgress, BatchImportOptions } from '../types';
import { EventEmitter } from '../utils/event';
import { DataAdapter } from '../utils/dataAdapter';

/**
 * 基础图层抽象类
 */
export abstract class BaseLayer extends EventEmitter {
  /** OpenLayers地图实例 */
  protected map: OlMap | null = null;
  /** OpenLayers图层实例 */
  protected layer: OlLayer | null = null;
  /** 图层配置 */
  protected options: BaseLayerOptions;
  /** 是否已初始化 */
  protected initialized: boolean = false;
  /** 数据适配器实例 */
  protected dataAdapter: DataAdapter | null = null;
  /** 业务数据存储 */
  protected businessData: Map<string, any> = new Map();
  /** 数据变化监听器 */
  private dataWatchers: Set<(data: any) => void> = new Set();
  /** 图层分组 */
  protected group: string | null = null;
  /** 权限配置 */
  protected permissions: { visible: boolean; editable: boolean } | null = null;

  /**
   * 构造函数
   * @param options 图层配置
   */
  constructor(options: BaseLayerOptions = {}) {
    super();
    this.options = {
      visible: true,
      opacity: 1,
      zIndex: 0,
      ...options
    };
    
    // 初始化分组
    this.group = options.group || null;
    
    // 初始化权限配置
    this.permissions = options.permissions || { visible: true, editable: true };
  }

  /**
   * 初始化图层
   * @param map OpenLayers地图实例
   */
  init(map: OlMap): void {
    if (this.initialized) {
      console.warn('Layer already initialized');
      return;
    }

    this.map = map;
    this.createLayer();
    this.applyOptions();
    this.map.addLayer(this.layer!);
    this.initialized = true;
    this.emit('init', this);
    
    // 设置可视范围控制
    this.setupVisibilityRangeControl();
  }
  
  /**
   * 设置可视范围控制
   */
  private setupVisibilityRangeControl(): void {
    if (this.options.visibilityRange && this.map) {
      const view = this.map.getView();
      
      // 初始检查
      this.updateVisibilityByZoom(view.getZoom());
      
      // 监听缩放变化
      view.on('change:resolution', () => {
        this.updateVisibilityByZoom(view.getZoom());
      });
    }
  }
  
  /**
   * 根据缩放级别更新图层可见性
   * @param zoom 当前缩放级别
   */
  private updateVisibilityByZoom(zoom: number | undefined): void {
    if (!this.options.visibilityRange || !this.layer || zoom === undefined) return;
    
    const { minZoom, maxZoom } = this.options.visibilityRange;
    const shouldBeVisible = 
      (minZoom === undefined || zoom >= minZoom) && 
      (maxZoom === undefined || zoom <= maxZoom);
    
    // 只有在权限允许的情况下才更新可见性
    const permissions = this.checkPermission({});
    if (permissions.visible) {
      this.layer.setVisible(shouldBeVisible && (this.options.visible ?? true));
    }
  }

  /**
   * 创建图层（子类实现）
   */
  protected abstract createLayer(): void;

  /**
   * 应用配置选项
   */
  protected applyOptions(): void {
    if (!this.layer) return;

    if (this.options.visible !== undefined) {
      this.layer.setVisible(this.options.visible);
    }

    if (this.options.opacity !== undefined) {
      this.layer.setOpacity(this.options.opacity);
    }

    if (this.options.zIndex !== undefined) {
      this.layer.setZIndex(this.options.zIndex);
    }

    if (this.options.minZoom !== undefined) {
      this.layer.setMinZoom(this.options.minZoom);
    }

    if (this.options.maxZoom !== undefined) {
      this.layer.setMaxZoom(this.options.maxZoom);
    }
  }

  /**
   * 初始化数据适配器
   * @param options 数据适配器配置
   */
  initDataAdapter(options: DataAdapterOptions): void {
    this.dataAdapter = new DataAdapter(options);
  }

  /**
   * 批量导入数据
   * @param data 原始数据
   * @param options 批量导入配置
   * @param onProgress 进度回调函数
   * @returns Promise<Feature[]> 转换后的要素数组
   */
  async batchImport(
    data: any[],
    options: BatchImportOptions = {},
    onProgress?: (progress: LoadProgress) => void
  ): Promise<Feature[]> {
    if (!this.dataAdapter) {
      throw new Error('Data adapter not initialized');
    }

    try {
      const features = await this.dataAdapter.batchImport(data, options, (progress) => {
        this.emit('dataLoading', progress);
        if (onProgress) {
          onProgress(progress);
        }
      });

      // 触发数据加载完成事件
      this.emit('dataLoaded', features);
      if (this.options.onDataLoaded) {
        this.options.onDataLoaded(features);
      }

      return features;
    } catch (error) {
      console.error('Batch import failed:', error);
      this.emit('dataError', error);
      throw error;
    }
  }

  /**
   * 绑定业务数据到图层
   * @param key 数据标识键
   * @param data 业务数据
   */
  bindData(key: string, data: any): void {
    this.businessData.set(key, data);
    this.notifyDataChange(key, data);
  }

  /**
   * 获取绑定的业务数据
   * @param key 数据标识键
   * @returns 业务数据
   */
  getData(key: string): any {
    return this.businessData.get(key);
  }

  /**
   * 监听数据变化
   * @param handler 数据变化处理函数
   * @returns 取消监听的函数
   */
  watchData(handler: (data: { key: string; value: any }) => void): () => void {
    this.dataWatchers.add(handler);
    return () => this.unwatchData(handler);
  }

  /**
   * 取消监听数据变化
   * @param handler 数据变化处理函数
   */
  unwatchData(handler: (data: { key: string; value: any }) => void): void {
    this.dataWatchers.delete(handler);
  }

  /**
   * 通知数据变化
   * @param key 数据标识键
   * @param value 数据值
   */
  protected notifyDataChange(key: string, value: any): void {
    const changeData = { key, value };
    this.dataWatchers.forEach(handler => {
      try {
        handler(changeData);
      } catch (error) {
        console.error('Data watcher error:', error);
      }
    });
    this.emit('dataChange', changeData);
  }

  /**
   * 设置图层分组
   * @param group 分组名称
   */
  setGroup(group: string): void {
    this.group = group;
  }

  /**
   * 获取图层分组
   * @returns 分组名称
   */
  getGroup(): string | null {
    return this.group;
  }

  /**
   * 设置图层权限
   * @param permissions 权限配置
   */
  setPermissions(permissions: { visible: boolean; editable: boolean }): void {
    this.permissions = { ...this.permissions, ...permissions };
    
    // 根据新的可见性权限更新图层显示
    if (this.layer) {
      this.layer.setVisible(this.permissions.visible);
    }
  }

  /**
   * 检查权限
   * @param role 角色信息
   * @returns 权限检查结果
   */
  checkPermission(role: any): { visible: boolean; editable: boolean } {
    // 基础实现，可由子类或业务方扩展
    return this.permissions || { visible: true, editable: true };
  }

  /**
   * 设置图层可见性
   * @param visible 是否可见
   */
  setVisible(visible: boolean): void {
    this.options.visible = visible;
    if (this.layer) {
      this.layer.setVisible(visible);
      this.emit('visiblechange', visible);
    }
  }

  /**
   * 获取图层可见性
   * @returns 是否可见
   */
  getVisible(): boolean {
    return this.layer?.getVisible() ?? this.options.visible ?? true;
  }

  /**
   * 设置图层透明度
   * @param opacity 透明度 0-1
   */
  setOpacity(opacity: number): void {
    this.options.opacity = opacity;
    if (this.layer) {
      this.layer.setOpacity(opacity);
      this.emit('opacitychange', opacity);
    }
  }

  /**
   * 获取图层透明度
   * @returns 透明度
   */
  getOpacity(): number {
    return this.layer?.getOpacity() ?? this.options.opacity ?? 1;
  }

  /**
   * 设置图层层级
   * @param zIndex 层级值
   */
  setZIndex(zIndex: number): void {
    this.options.zIndex = zIndex;
    if (this.layer) {
      this.layer.setZIndex(zIndex);
      this.emit('zindexchange', zIndex);
    }
  }

  /**
   * 获取图层层级
   * @returns 层级值
   */
  getZIndex(): number {
    return this.layer?.getZIndex() ?? this.options.zIndex ?? 0;
  }

  /**
   * 设置最小缩放级别
   * @param minZoom 最小缩放级别
   */
  setMinZoom(minZoom: number): void {
    this.options.minZoom = minZoom;
    if (this.layer) {
      this.layer.setMinZoom(minZoom);
    }
  }

  /**
   * 设置最大缩放级别
   * @param maxZoom 最大缩放级别
   */
  setMaxZoom(maxZoom: number): void {
    this.options.maxZoom = maxZoom;
    if (this.layer) {
      this.layer.setMaxZoom(maxZoom);
    }
  }

  /**
   * 获取OpenLayers图层实例
   * @returns OpenLayers图层实例
   */
  getLayer(): OlLayer | null {
    return this.layer;
  }

  /**
   * 获取OpenLayers地图实例
   * @returns OpenLayers地图实例
   */
  getMap(): OlMap | null {
    return this.map;
  }

  /**
   * 更新图层配置
   * @param options 新的配置选项
   */
  updateOptions(options: Partial<BaseLayerOptions>): void {
    (this.options as any) = { ...this.options, ...options };
    this.applyOptions();
    this.emit('optionschange', this.options);
  }

  /**
   * 销毁图层
   */
  destroy(): void {
    if (this.map && this.layer) {
      this.map.removeLayer(this.layer);
    }
    this.removeAllListeners();
    this.map = null;
    this.layer = null;
    this.initialized = false;
    this.emit('destroy', this);
  }

  /**
   * 获取图层ID
   * @returns 图层ID
   */
  getId(): string | undefined {
    return this.options.id;
  }

  /**
   * 获取图层名称
   * @returns 图层名称
   */
  getName(): string | undefined {
    return this.options.name;
  }

  /**
   * 设置图层名称
   * @param name 图层名称
   */
  setName(name: string): void {
    this.options.name = name;
  }

  /**
   * 使用数据适配器加载数据
   * @param data 原始数据
   * @param adapterOptions 数据适配器配置
   * @param importOptions 导入配置
   * @param onProgress 进度回调函数
   * @returns Promise<void>
   */
  async loadDataWithAdapter(
    data: any[],
    adapterOptions: DataAdapterOptions,
    importOptions: BatchImportOptions = {},
    onProgress?: (progress: LoadProgress) => void
  ): Promise<void> {
    throw new Error('loadDataWithAdapter not implemented');
  }
}

